# 头条极速版
import json
import random
import re
import time

from PySide6.QtCore import Qt
from PySide6.QtWidgets import QTableWidgetItem

from common.mytRpc import MytRpc
from ikuai import IKuai
from utils import *


class Toutiao(object):
    def __init__(self, android, devinfo):
        self.devinfo = devinfo
        self.android = android
        self.finish = False
        if "task" in android and android['task']:
            self.app_number = android['task']['devinfo']['app_number']
            self.app_type = android['task']['app_type']
            self.user_wait = android['task']['user_wait']
        else:
            self.app_number = devinfo['app_number']
            self.app_type = 1
            self.user_wait = False
        self.connect_state = False
        self.mytapi = MytRpc()
        # 这里错误
        port = int(android['RPC'].split(":")[1])
        win_log(f"SDK 版本号:  {self.mytapi.get_sdk_version()} IP {android['ip']} prot {port}  ", '', android['Name'])
        app_msg = f"小程序名 {devinfo['app_name']}({devinfo['app_id']}) 真机ID {devinfo['devinfo_id']} 任务ID:{devinfo['auto_id']}"
        win_log(app_msg, '', android['Name'])
        if self.mytapi.init(android['ip'], port, 5) == True:
            if self.mytapi.check_connect_state() == True:
                self.log(f"{android['ip']}当前连接状态正常", '连接正常')
                self.connect_state = True
            else:
                self.log(f"{android['ip']}当前连接断开", '连接断开', 1)
        else:
            self.log("RPC连接失败", '连接失败', 1)

        self.set_table_item(5, 1)
        self.update_count()

    def start_test(self):
        while True:
            if self.tt_count <= 0:
                break
            self.tt_count -= 1
            self.js_count -= 1
            self.save_task()
            self.time_sleep(10)

        self.finish_task()

    # 1、启动函数
    def start(self):
        self.save_task()

        task = {
            "1": {"name": "极速"},
            "2": {"name": "头条"},
            "3": {"name": "抖音"},
            "4": {"name": "抖音极速"},
        }

        for app_type in task:
            print("app_type",app_type)
            print("self.app_number",self.app_number)
            while self.app_number[app_type] > 0 and self.finish == False:
                res = self.open_min_app(app_type)
                if res == True:
                    self.log("当前打开小程序成功", '打开成功')
                    while self.app_number[app_type] > 0 and self.finish == False:
                        res = self.start_click_ad(app_type)
                        if res == False:
                            self.log('看广告失败了', '头条看广告失败了')
                            self.stop_app(app_type)
                            self.open_min_app(app_type)
                        else:
                            self.log(f'{app_type}看完一条', f'{app_type}看完一条')
                            self.time_sleep(random.randint(10, 15))
                else:
                    self.stop_app(app_type)
                    self.log("当前打开小程序失败", '打开失败', 1)
            self.stop_app(app_type)
            self.time_sleep(3)
        self.finish_task()

    # 2、开始执行点广告
    def start_click_ad(self, app_type):
        # 首先点击左边空白然后，然后点击查看答案关闭弹窗
        max_count = 10
        show_ad_count = 10
        while True:
            if max_count <= 0:
                self.stop_app(1)
                self.stop_app(2)
                self.log("执行查看广告超出次数", '查广告超次数', 1)
                DkGlobal().android_docker.restart_android(self.android)
                self.time_sleep(10)
                max_count = 10
                self.open_min_app(app_type)

            page = self.get_page_name()
            if "小程序页面" in page or "查看答案" in page or "广告弹窗确认" in page or "答案弹窗" in page:
                self.mytapi.touchClick(1, 690, 635)
                self.time_sleep(2)
                self.mytapi.clickText("确认")
                self.time_sleep(2)
                self.mytapi.clickText("查看答案")
                self.log("点击查看答案", '查看答案')
                self.time_sleep(2)
                # 判断是否有广告确认框，并且没有显示广告页面
                page = self.get_page_name()
                if "广告弹窗确认" in page and "广告页面" not in page:
                    self.log("点击广告弹窗确认", "确认弹窗")
                    self.mytapi.clickText("确定")
                    if show_ad_count <= 0:
                        self.js_count = 0
                        self.tt_count = 0
                        return False
                    show_ad_count -= 0
                    # self.time_sleep(5)
                    time_count = 5
                    while time_count > 0:
                        if "adErr:1004" in self.getXml():
                            self.log("当前没有适合的广告或者报错了", '报错了', 1)
                            # self.js_count = 0
                            # self.tt_count = 0
                            self.finish = True
                            ServerApi().set_devinfo_close(self.devinfo, "无适合的广告")
                            return False

                        elif "adErr:" in self.getXml():
                            self.log("当前其他错误码报错", '报错', 1)
                            # self.js_count = 0
                            # self.tt_count = 0
                            self.finish = True
                            return False

                        time.sleep(1)
                        time_count -= 1

                self.time_sleep(3)
                page = self.get_page_name()
                if "广告页面" in page or "等待广告" in page:
                    self.log("广告显示成功", '等待广告')
                    break
                self.time_sleep(3)
                if "看完广告" in self.get_page_name():
                    self.log("奇怪了，看完广告了？", '看完广告')
                    break
                page = self.get_page_name()
                if "小程序页面" not in page and "答案弹窗" not in page:
                    self.log("没有在小程序页面", "没有小程序页")
                self.log("查看广告失败了，可能广告没有加载出来", "广告没加载")
                self.time_sleep(4)
            else:
                self.stop_app(app_type)
                time.sleep(5)
                self.open_min_app(app_type)
                self.log("重启和启动")
                time.sleep(10)
            max_count -= 1
        max_count = 3
        # 广告页面已经出来了等待广告加载完毕
        while True:
            if max_count <= 0:
                self.log("看完等待了3次了", '看完等待3次')
                self.stop_app(1)
                self.time_sleep(5)
                self.open_min_app(app_type)
                return False
            self.log("判断小程序页面", '判断小程序页')
            if "小程序页面" not in self.get_page_name():
                self.log("小程序页面")
                return False
            ad_time = self.extract_ad_seconds(self.getXml())
            if ad_time:
                self.log(f"等待广告还是{ad_time}秒，多等待20秒", "看完等待")
                self.time_sleep(ad_time + 20)
                self.mytapi.clickText("立即下载")
                self.mytapi.clickText("免费下载")
                self.mytapi.clickText("即刻下载")
                self.time_sleep(1)
                self.mytapi.clickText("不允许")
                self.time_sleep(2)
                max_count -= 1
            page = self.get_page_name()
            self.log("判断广告内页", '判断广告内页')
            if "广告内页" in page:
                self.log("进入了广告内页", "广告内页")
                self.time_sleep(3)
                self.mytapi.clickDesc("返回")
                self.time_sleep(3)
            self.log("判断看完广告", '判断看完广告')
            if "广告失败" in page:
                self.mytapi.touchClick(1, 648, 100)
                self.time_sleep(2)
                self.mytapi.clickText("坚持退出")
                return False
            if "看完广告" in page:
                self.mytapi.touchClick(1, 48, 112)
                self.time_sleep(5)
                self.log("看完广告，领取奖励页面", "看完广告")
                self.time_sleep(3)
                self.mytapi.clickText("领取成功")
                # if app_type == 1:
                #     self.js_count -= 1
                #     self.log(f"极速版看完1条，还剩{self.js_count}条", '看完1次')
                # else:
                #     self.tt_count -= 1
                #     self.log(f"头条看完1条，还剩{self.js_count}条", '看完1次')
                self.app_number[app_type] -= 1
                self.log(f"{app_type}看完1条，还剩{self.app_number[app_type]}条", '看完1次')
                self.update_count()
                ServerApi().set_devinfo_used(self.devinfo['app_id'], self.devinfo['devinfo_id'], self.devinfo['auto_id'], app_type)
                # 保存一下任务
                self.save_task()
                return True

    # 进入小程序
    def open_min_app(self, app_type, def_count=0):
        if def_count > 0:
            # TODO 这里一直是失败一次
            if DkGlobal().android_docker !=None:
                app_type_name = {1: 'js', 2: 'tt', 3: 'dy', 4: 'dy_lite'}
                DkGlobal().android_docker.install_apk(self.android, app_type_name[app_type])
            self.log(f"打开小程序失败{def_count}次 {app_type}", f'打开小程序{def_count}次', 1)
        if def_count >= 3:
            self.log(f"打开小程序失败超过最大次数(open_min_app_over) type:{app_type}", '小程序超次数', 1)
            self.stop_app(app_type)
            self.open_min_app(app_type, 0)
            return False
        # 执行个人中心页面等待
        if app_type == 1:
            self.handle_user_wait()
        if app_type == 2:
            self.log("判断头条首页", "判断头条首页")
            if "头条首页" in self.get_page_name():
                self.log("到了头条首页")
                return False
        if app_type == 3:
            # 抖音
            pass
        if app_type == 4:
            pass
        # 执行打开小程序
        self.log("打开小程序", "打开小程序")
        self.open_scheme(app_type)
        self.log("组件加载完毕，马上进入小程序首页", '组件加载完毕')
        self.time_sleep(3)
        # 这里已经在小程序页面了，但是可能小程序不一定能加载出来，加载3次没出来就关闭重进
        wait_count = 0
        while True:
            if wait_count > 5:
                self.log("打开小程序等待次数超出了", '超出等待', 1)
                return False
            self.open_scheme(app_type)
            self.log("判断小程序加载失败", "判断小程序加载失败")
            while "com.ss.android.ugc.aweme.lite:id/progress" in self.getXml():
                self.log("当前在抖音/抖音极速页面等待加载小程序", '等待加载')
                time.sleep(20)
            while "com.ss.android.ugc.aweme:id/progress" in self.getXml():
                self.log("当前在抖音/抖音极速页面等待加载小程序", '等待加载')
                time.sleep(20)
            if "小程序加载失败" in self.get_page_name():
                self.log("小程序加载失败", '加载失败', 1)
                self.stop_app(app_type)
                self.time_sleep(1)
                self.log(f"关闭小程序，类型：{app_type}")
                self.open_scheme(app_type)
                self.log(f"启动小程序，类型：{app_type}")
                self.time_sleep(5)
            self.mytapi.clickText("知道了")
            self.mytapi.clickText("以后再说")
            self.log("判断LOGO加载", "判断LOGO")
            self.time_sleep(5)
            while "加载LOGO" in self.get_page_name():
                self.log("等待加载LOGO", "LOGO...")
                self.time_sleep(10)
            self.log("判断首次", "判断首次")
            self.time_sleep(2)
            progress = ""
            first_count = 0
            while True:
                xml = self.getXml()
                if "首次使用小程序" in xml:
                    pattern = r'首次使用小程序，准备中(\d+)%…'
                    match = re.search(pattern, xml)
                    if match is None:
                        self.log("当前match为None", '无进度')
                        break
                    try:
                        if first_count % 4 == 0 and progress == match.group(1):
                            self.log("首次加载的进度条一直没变化", '进度条无变化', 1)
                            self.stop_app(app_type)
                            self.time_sleep(3)
                            self.open_min_app(app_type)
                            self.time_sleep(10)
                            self.open_scheme(app_type)
                        else:
                            self.log("首页等待", '首页等待')
                            progress = match.group(1)
                            self.time_sleep(20)
                    except Exception as e:
                        self.log(f'报错了，e:{e}', '', 1)
                        break
                    first_count += 1
                else:
                    self.log("没有在首次使用界面了", '没在使用界面')
                    break
            self.log("判断加载组件", "判断加载组件")
            self.time_sleep(2)
            while "加载组件" in self.get_page_name():
                self.log("等待加载组件", "加载组件")
                self.time_sleep(5)
            self.log("判断查看答案", "判断查看答案")
            self.time_sleep(2)

            if "头条首页" in self.get_page_name():
                self.open_scheme(app_type)

            if "查看答案" in self.get_page_name():
                self.log("进入小程序首页", '小程序首页')
                return True
            self.time_sleep(5)
            wait_count += 1

    # 重启小程序
    def stop_app(self, app_type):
        pkgs= {
            "1":"com.ss.android.article.lite",
            "2": "com.ss.android.article.news",
            "3": "com.ss.android.ugc.aweme",
            "4": "com.ss.android.ugc.aweme.lite",
        }
        self.mytapi.stopApp(pkgs[app_type])
        self.log('正在关闭程序', '关闭程序')
        self.time_sleep(3)

    # 刷新IP
    def refresh_ip(self, reason=""):
        self.log(f'{reason}刷新当前ip', f'{reason}刷新IP')
        IKuai().refresh_ip(self.android, True)
        self.time_sleep(3)

    # 个人中心等待
    def handle_user_wait(self, def_count=0):
        if self.user_wait:
            self.log("当前无需等待了")
            return False
        self.log("当前需要在个人中心等待")
        if def_count > 0:
            self.log(f"进入头条极速个人中心失败{def_count}次", f'个人中心失败{def_count}次', 1)
        if def_count >= 10:
            self.log(f"进入头条极速个人中心失败超出最大次数", '个人中心失败超出', 1)
            return False
        self.mytapi.openApp("com.ss.android.article.lite")
        self.time_sleep(10)
        self.log('打开进入头条极速版', '打开头条极速')
        open_app_count = 0
        while True:
            page = self.get_page_name()
            if "头条极速首页" in page:
                self.log('成功打开头条极速版首页', '正在极速首页')
                break
            if "极速个人中心" in page:
                self.log('成功打开头条极速版个人中心页面', '正在个人中心页面')
                break
            self.log("重新打开极速版APP", '重新打开极速版')
            if open_app_count > 3:
                self.log("重新安装程序", '安装程序')
                DkGlobal().android_docker.install_apk(self.android, 'js')
                self.time_sleep(2)
                open_app_count = 0
            self.mytapi.openApp("com.ss.android.article.lite")
            if "头条极速首页" in page:
                break
            self.time_sleep(10)
            open_app_count += 1

        self.mytapi.clickText('未登录')
        self.time_sleep(10)
        while True:
            page = self.get_page_name()
            if "极速个人中心" in page:
                self.log("成功进入极速版个人中心页面", '极速个人中心')
                self.time_sleep(random.randint(200, 240))
                self.user_wait = True
                break
            else:
                self.log("还未进入个人中心", 'NO个人中心')
                self.time_sleep(10)
        self.handle_user_wait(def_count + 1)

    # 倒计时
    def time_sleep(self, _time):
        while True:
            if _time <= 0:
                break
            time.sleep(1)
            _time -= 1
            self.set_table_item(7, _time)

    def getXml(self):
        res = self.mytapi.dumpNodeXml(True)
        if res == False:
            self.stop_app(1)
            self.stop_app(2)
            self.time_sleep(2)
            if DkGlobal().android_docker is not None:
                DkGlobal().android_docker.restart_android(self.android)
        else:
            return res

    # 获取页面名称
    def get_page_name(self):
        if self.mytapi == None:
            return []
        pages = []
        xml = str(self.getXml())
        # print(xml)
        if "文件管理" in xml and "扩展服务" in xml:
            pages.append("系统首页")
        if "关注" in xml and "推荐" in xml:
            pages.append("头条极速首页")
        if "个人信息保护指引" in xml:
            pages.append("隐私协议")
            print("发现隐私协议")
            self.log("发现隐私协议", '隐私协议')
            self.time_sleep(3)
            self.mytapi.clickText("同意")
        if "你收到一个现金红" in xml or "恭喜获得现金红包" in xml or "提现至支付宝" in xml or "开红包" in xml:
            pages.append("红包")
            self.log("发现红包弹窗", '红包')
            self.time_sleep(3)
            self.mytapi.clickDesc("关闭")
            self.mytapi.clickId("com.ss.android.ugc.aweme.lite:id/c2v")
        if ("头条" in xml and "我的" in xml) or ("头条" in xml and "未登录" in xml):
            pages.append("头条首页")
        if "登录体验 完整功能" in xml:
            pages.append("头条登录页")
        if self.connect_state:
            res = self.mytapi.getNodeByText("未登录")
            if res != None:
                if json.loads(res)[0]['selected']:
                    pages.append("极速个人中心")
        if "microapp_m_loading_icon" in xml and "小程序加载失败" not in xml:
            pages.append("加载LOGO")
        if "首次使用小程序" in xml:
            pages.append("首次小程序")
        if "正在加载页面" in xml:
            pages.append("加载组件")
        if "点击退出小程序" in xml:
            pages.append("小程序页面")
        if "查看答案" in xml:
            pages.append("查看答案")
        if "查看答案需要看广告" in xml:
            pages.append("广告弹窗确认")
        if "广告" in xml and "开启声音" in xml:
            pages.append("广告页面")
        if "广告" in xml and "秒后可领奖励" in xml:
            pages.append("等待广告")
        if "返回" in xml and "bdp_titlebar_back" not in xml:
            pages.append("广告内页")
        if "领取成功" in xml:
            pages.append("看完广告")
        if "立即下载" in xml:
            pages.append("立即下载")
        if "视频加载失败，请重试" in xml:
            pages.append('广告失败')
        if "升级版本" in xml:
            self.log("提示升级版本，自动关闭", '升级版本')
            self.time_sleep(3)
            self.mytapi.clickDesc('关闭')

        if "小程序加载失败" in xml:
            pages.append("小程序加载失败")
        if "确认" in xml and "正确答案" in xml:
            pages.append("答案弹窗")

        print("get_page_name", self.android['Name'], pages)
        return pages

    # 打开小程序
    def open_scheme(self, app_type):
        scheme_type = {
            "1": 'snssdk35',
            "2": 'snssdk141',
            "3": 'snssdk1128',
            "4": 'snssdk2329',
        }
        scheme = f"{scheme_type[app_type]}://microapp?app_id={self.devinfo['appid']}&bdp_log=%7B%22launch_from%22%3A%22ad%22%2C%22location%22%3A%22%22%7D&scene=0&start_page=pages%2Fquestion%2Fad%3F&version=v2&version_type=current&bdpsum=880db2b"
        cmd = f"am start -a android.intent.action.VIEW -d \"{scheme}\""
        return self.mytapi.exec_cmd(cmd)

    # 记录日志
    def log(self, content, status=None, error=0):

        type = ''
        if error == 1:
            type = 'error'
        content = f"{self.android['Name']}-{self.devinfo['app_name']}:{content}"
        print(f"content:{type} {content} status:{status}")
        if status:
            self.set_android_status(status)
            pass
        if content:
            win_log(content, type, self.android['Name'])

    # 设置安卓机状态
    def set_android_status(self, status):
        if DkGlobal().android_docker != None and DkGlobal().body != None:
            keys = list(DkGlobal().android_docker.android_list.keys())
            row = keys.index(self.android['ip'])
            item = QTableWidgetItem(str(status))  # 将数据转换成字符串形式
            item.setTextAlignment(Qt.AlignCenter)
            DkGlobal().body.tableWidget.setItem(row, 6, item)

    # 设置表格
    def set_table_item(self, role, item):
        if DkGlobal().android_docker != None and DkGlobal().body != None:
            # self.app_type = item
            keys = list(DkGlobal().android_docker.android_list.keys())
            row = keys.index(self.android['ip'])
            item = QTableWidgetItem(str(item))
            item.setTextAlignment(Qt.AlignCenter)
            DkGlobal().body.tableWidget.setItem(row, role, item)

    # 更新表格统计
    def update_count(self):
        print("self.devinfo['app_number']",self.devinfo['app_number'])
        app_number = self.devinfo['app_number']
        item = f"{app_number['1']} - {app_number['2']}-{app_number['3']}-{app_number['4']}"
        self.set_table_item(1, item)

    # 获取广告时间
    def extract_ad_seconds(self, xml_content):
        pattern = r'(\d+)秒后可领奖励'
        match = re.search(pattern, xml_content)
        if match:
            # 提取秒数
            seconds = int(match.group(1))
            return seconds
        else:
            return 0

    # TODO 保存任务进度
    def save_task(self):
        if DkGlobal().android_docker:
            app_number = self.devinfo['app_number']
            progress = f"{app_number['1']} - {app_number['2']}-{app_number['3']}-{app_number['4']}"
            DkGlobal().android_docker.android_list[self.android['ip']]['task'] = {
                "app_name": self.devinfo['app_name'],
                "progress": progress,
                "app_type": self.app_type,
                # 个人中心等待
                "user_wait": self.user_wait,
                # 真机信息
                "devinfo": self.devinfo,
            }
            DkGlobal().android_docker.save_task()

    def finish_task(self):
        DkGlobal().android_docker.android_list[self.android['ip']]['task'] = None
        DkGlobal().android_docker.save_task()
        DkGlobal().android_docker.update_table()

    # 检查网络
    def check_network(self):
        pass


if __name__ == '__main__':
    # devinfo = {'app_name': '智慧学习港', 'app_id': 8, 'appid': 'tt4fb7390ad08039e101', 'mode': '1', 'auto_id': 3, 'devinfo_id': 266, 'app_type': 2}
    devinfo = {"app_name": "智慧谷",
               "app_id": 14,
               "appid": "tt1b816d3c84b608de01",
               "mode": "1",
               "auto_id": 3,
               "devinfo_id": 189,
               "app_type": 1,
               "app_number": {
                   1: 5,
                   2: 1,
                   3: 5,
                   4: 1
               },
               }
    android = getTestAndroid(4)
    self = Toutiao(android, devinfo)
    # self.get_page_name()
    # self.open_scheme(3)
    # time.sleep(1)
    print(self.getXml())

    # com.ss.android.ugc.aweme.lite: id / progress

    # self.open_scheme(4)
    # self.stop_app(1)

    # time.sleep(5)
    # self.open_scheme(1)
    # self.log("重启和启动")
    # time.sleep(10)
